package com.cac.demo.controller.directDelivery;

import com.alibaba.fastjson.JSON;
import com.cac.demo.dao.directDelivery.DirectDeliveryDao;
import com.cac.demo.dao.msAoMatchInfo.MsAoMatchInfoDao;
import com.cac.demo.dao.msTaskAo.MsTaskAoDao;
import com.cac.demo.dao.msTaskPackage.MsTaskPackageDao;
import com.cac.demo.dao.outStoreRoom.OutStoreroomDao;
import com.cac.demo.service.directDelivery.DirectDeliveryService;
import com.cac.demo.util.CreateCommonLog;
import com.cac.demo.util.ExceptionToStirng;
import com.cac.demo.util.adapter.*;
import lombok.extern.slf4j.Slf4j;
import net.logstash.logback.encoder.org.apache.commons.lang.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * @className: DirectDeliveryRest
 * @description: （描述这个类的作用）
 * @author: lqc
 * @date: 2023/7/10 15:04:04 周一
 * @version: 1.0
 */
@RestController
@RequestMapping("/DirectDeliveryRest")
@Slf4j
public class DirectDeliveryRest {

    @Autowired
    private DirectDeliveryService directDeliveryService;
    @Autowired
    private DirectDeliveryDao directDeliveryDao;
    @Autowired
    private OutStoreroomDao outStoreroomDao;
    @Autowired
    private MsAoMatchInfoDao msAoMatchInfoDao;
    @Autowired
    private MsTaskPackageDao msTaskPackageDao;
    @Autowired
    private MsTaskAoDao msTaskAoDao;
    @Autowired
    private TransactionDefinition transactionDefinition;
    @Autowired
    private PlatformTransactionManager platformTransactionManager;
    @Autowired
    private CreateCommonLog createCommonLog;
    @Autowired
    private Environment environment;

    //接收直配查询
    @PostMapping("/searchByPage")
    public ResponseMsg<QueryRespBean<HashMap>> searchByPage(@RequestBody Map map) {
        ResponseMsg<QueryRespBean<HashMap>> responseMsg = new ResponseMsg<>();
        String page = JSON.toJSONString(map.get("pageParameter"));
        PageParameter pageParameter = JSON.parseObject(page, PageParameter.class);
        String DTO = JSON.toJSONString(map.get("searchParams"));
        HashMap searchParams = JSON.parseObject(DTO, HashMap.class);
        QueryReqBean<HashMap> queryReqBean = new QueryReqBean<>();
        queryReqBean.setPageParameter(pageParameter);
        queryReqBean.setSearchParams(searchParams);
        QueryRespBean<HashMap> result = directDeliveryService.searchByPage(queryReqBean);
        responseMsg.setResponseBody(result);
        return responseMsg;
    }

    //接收直配
    @PostMapping("/directDelivery")
    public ResponseMsg directDelivery(@RequestBody List<HashMap> list) {
        ResponseMsg responseMsg = new ResponseMsg();
        if(list.size()==0){
            return responseMsg.setRetCode("201").setMessage("200");
        }
        HashMap map = new HashMap();
        map = list.get(0);
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String IP = null;
        if (request.getHeader("x-forwarded-for") == null) {
            IP = request.getRemoteAddr();
        } else {
            IP = request.getHeader("x-forwarded-for");
        }
        String userCode = (String) request.getSession().getAttribute("account");
        if (Objects.isNull(userCode)) {
            return responseMsg.setMessage("登陆过期，请重新登陆！").setRetCode("201");
        }

        int remainQty = 0;
        TransactionStatus transaction = platformTransactionManager.getTransaction(transactionDefinition);
        try {
            //查询此交接单是否入库,若已入库，则不在进行入库操作
            List<HashMap> itemInventorys = directDeliveryDao.queryItemInventoryInfo(map);
            if(itemInventorys.size()==0){
                map.put("IP", IP);
                map.put("userCode", userCode);
                //修改交接单状态
                directDeliveryDao.updateWmsDeliveryPlan(map);
                String Hid = ComUtil.getId();//主表id
                String Lid = ComUtil.getId();//子表id
                String itemId = ComUtil.getId();//台账id
                map.put("Hid", Hid);
                map.put("Lid", Lid);
                map.put("itemId", itemId);
                log.info("//新增主表数据");
                //新增主表数据
                directDeliveryDao.insertWmsInvInBillH(map);
                log.info("//新增子表数据");
                //新增子表数据
                directDeliveryDao.insertWmsInvInBillL(map);
                log.info("//新增台账");
                //新增台账
                directDeliveryDao.insertWmsItemInventory(map);
                log.info("//新增流水");
                //新增流水
                directDeliveryDao.insertWmsItemTransaction(map);
                log.info("//新增库存");
                //发送台账信息到ERP
                directDeliveryService.sendParamToErp(map);
                remainQty = Integer.parseInt(map.get("deliveryQty").toString());
                itemInventorys = directDeliveryDao.queryItemInventoryInfo(map);
            }else{
                remainQty = Integer.parseInt(itemInventorys.get(0).get("currentOnhandQty").toString());
            }
            //创建新的交接单，托盘与小车绑定关系，更改占用信息
            List<String> toolCodes = new ArrayList<>();

            toolCodes.add("212080030000");
            for(HashMap tmp : list){
                if(remainQty==0){
                    break;
                }
                tmp.put("IP", IP);
                tmp.put("userCode", userCode);
                HashMap newMatchInfoMap = new HashMap();
                //入库后直接分拣 1.占用信息，2.配套信息3.计划
                //新增配套信息，计算分拣配套数量
                String msAoMatchInfoId = ComUtil.getId();
                int packageCount = directDeliveryDao.queryPackageQtyByInfoId(tmp);
                int itemQty = Integer.parseInt(tmp.get("itemQty").toString());
                if(itemQty>packageCount){
                    if(remainQty>=itemQty-packageCount){
                        tmp.put("itemQty",itemQty-packageCount);//设置实际分拣保存数量
                        newMatchInfoMap.put("packageCount",itemQty-packageCount);
                        newMatchInfoMap.put("state","02");
                        remainQty = remainQty -(itemQty-packageCount);

                    }else{
                        tmp.put("itemQty",remainQty);//设置实际分拣保存数量
                        newMatchInfoMap.put("packageCount",remainQty);
                        remainQty = 0;
                        if(itemQty>packageCount){
                            newMatchInfoMap.put("state","04");
                        }else{
                            newMatchInfoMap.put("state","02");
                        }
                    }
                }else{
                    continue;
                }
                //新增库存
                directDeliveryDao.insertMsWorkbinMaterial(tmp);
                newMatchInfoMap.put("msAoMatchInfoId",msAoMatchInfoId);
                newMatchInfoMap.put("oldMsAoMatchInfoId",tmp.get("msAoMatchInfoId"));
                newMatchInfoMap.put("wmsItemInventoryId",tmp.get("itemId"));
                newMatchInfoMap.put("qualityCode",itemInventorys.get(0).get("qualityCode"));
                newMatchInfoMap.put("mesCheckQualiticationId",itemInventorys.get(0).get("mesCheckQualiticationId"));
                newMatchInfoMap.put("wmsItemInventoryId",tmp.get("itemId"));
                newMatchInfoMap.put("barcode",itemInventorys.get(0).get("barcode"));
                //插入一条新的matchInfo数据
                directDeliveryDao.addMatchInfo(newMatchInfoMap);
                //更新原来那条match_info数据状态--只更新未分拣状态为01的数据，状态为04的不做处理
                directDeliveryDao.deleteOldMatchInfo(newMatchInfoMap);
                //分拣保存
                tmp.put("msAoMatchInfoId",msAoMatchInfoId);
                directDeliveryDao.saveToolCode(tmp);
                //创建占用信息
                String wmsInvOutAllotmentId = ComUtil.getId();
                tmp.put("wmsInvOutAllotmentId", wmsInvOutAllotmentId);
                directDeliveryDao.insertAllotment(tmp);
                //分拣占用信息上传ERP
                directDeliveryService.allBData(tmp);
                //判断当前AO是否还有物料未分拣
                int isFianlAoMaterail = msAoMatchInfoDao.isNoSortMaterail(tmp);
                //部分分拣，增加package标识
                msTaskPackageDao.addSortingRemark((String) tmp.get("msTaskAoId"));
                //没有AO存在未分拣物料，表明AO已分拣完成，进入工作包任务中检查是否全部工作包下的AO已分拣完毕
                if (isFianlAoMaterail == 0) {
                    //更新AO分拣状态
                    msTaskAoDao.updateAo((String) tmp.get("msTaskAoId"));
                    //查询该AO是否为所属工作包最后一个，是修改工作包状态，否不做操作
                    int isFinalAo = msTaskAoDao.isFinalAo((String) tmp.get("msTaskAoId"));
                    //isFinal=0时，证明该ao所属的工作包任务已经分拣完成
                    if (isFinalAo == 0) {
                        //修改工作包任务状态
                        responseMsg.setMessage("工作包任务已分拣完成");
                        msTaskPackageDao.changePackageStatu((String) tmp.get("msTaskAoId"));
                    } else {
                        responseMsg.setMessage("当前工作包任务中还有AO未分拣完成");
                    }
                } else {
                    //yebo 部分分拣修改AO状态
                    msTaskAoDao.updateAoStatusForSome((String) tmp.get("msTaskAoId"));
                    responseMsg.setMessage("AO物料未全部分拣！");
                }
                //更新台账
                directDeliveryDao.updateOccupy(tmp);
            }
            //如果直配数量有剩余，则进行入库操作
            if(remainQty>0){
                //获取箱子
                //判断当前是标准件还是零件
                int cnt = directDeliveryDao.queryDeliveryType(map);
                HashMap callMap = new HashMap();
                callMap.put("i_item_code",map.get("itemCode"));
                callMap.put("i_item_qty",remainQty);
                callMap.put("i_ip",IP);
                callMap.put("i_material_barcode",map.get("barcode"));
                callMap.put("i_wms_delivery_plan_id",map.get("wmsDeliveryPlanId"));
                if(cnt==0){//零件成品
                    outStoreroomDao.searchWorkbinCode(callMap);
                }else{//标准件
                    outStoreroomDao.searchWorkbinCodeForBzj(callMap);
                }
                //喊箱子
                log.info("直配喊箱子==================="+callMap.toString());
                if("0".equals(callMap.get("o_Return_Int"))){
                 /*   HashMap callWcsMap = new HashMap();
                    createCommonLog.callWCSInterface(callWcsMap);*/
                    HashMap tp = new HashMap();
                    tp.put("wmsDeliveryPlanId",map.get("wmsDeliveryPlanId"));
                    tp.put("palletCodes",callMap.get("o_Return_String"));
                    directDeliveryDao.updateDeliveryPalletCode(tp);
                }

            }
            platformTransactionManager.commit(transaction);
            //配送创建新的交接单，小车信息,发送物料数据到erp
            directDeliveryService.dispatch("L-D-00000015", toolCodes, map);

        } catch (Exception e) {
            e.printStackTrace();
            platformTransactionManager.rollback(transaction);
            responseMsg.setMessage("程序异常").setRetCode("201").setErrorDesc(ExceptionToStirng.getExceptionToString(e));
        } finally {
            return responseMsg;
        }
    }
}
